﻿#include "lightning.h"
#include "runtime.h"
#include "evaluate.h"
#include "context.h"

// 使用 extern "C" 指示编译器使用 C 链接方式而不是 C++，这使得函数可以被其他 C 代码调用
extern "C"
{
	// 创建上下文对象，根据传入的 context_type (ctx_type) 创建对应的 runtime 或 evaluate 对象
	ltobj lt_create_context(context_type ctx_type, const char* config_path)
	{
		ltobj lt; // 定义一个 ltobj 对象，ltobj 是一个结构体，可能包含指向 context 对象的指针和上下文类型信息
		lt.obj_type = ctx_type; // 设置 lt 对象的类型为传入的上下文类型

		if (ctx_type == CT_RUNTIME) // 如果类型是 runtime 类型
		{
			auto obj = new runtime(); // 创建一个 runtime 对象
			if (!obj->init_from_file(config_path)) // 如果从配置文件初始化失败
			{
				delete obj; // 删除 runtime 对象，释放内存
				obj = nullptr; // 将指针设为 nullptr
			}
			lt.obj_ptr = obj; // 将对象指针存储在 ltobj 的 obj_ptr 中
			return lt; // 返回 ltobj 对象
		}

		if (ctx_type == CT_EVALUATE) // 如果类型是 evaluate 类型
		{
			auto obj = new evaluate(); // 创建一个 evaluate 对象
			if (!obj->init_from_file(config_path)) // 如果从配置文件初始化失败
			{
				delete obj; // 删除 evaluate 对象，释放内存
				obj = nullptr; // 将指针设为 nullptr
			}
			lt.obj_ptr = obj; // 将对象指针存储在 ltobj 的 obj_ptr 中
			return lt; // 返回 ltobj 对象
		}

		lt.obj_ptr = nullptr; // 如果类型不匹配，设置对象指针为 nullptr
		return lt; // 返回 ltobj 对象
	}

	// 销毁上下文对象
	void lt_destory_context(ltobj& lt)
	{
		if (lt.obj_ptr) // 如果 obj_ptr 不为空
		{
			if (lt.obj_type == CT_RUNTIME) // 如果对象类型是 runtime
			{
				runtime* obj = (runtime*)lt.obj_ptr; // 将 obj_ptr 转换为 runtime 指针
				delete obj; // 删除 runtime 对象
				lt.obj_ptr = nullptr; // 将 obj_ptr 设置为 nullptr
			}
			else if (lt.obj_type == CT_EVALUATE) // 如果对象类型是 evaluate
			{
				evaluate* obj = (evaluate*)lt.obj_ptr; // 将 obj_ptr 转换为 evaluate 指针
				delete obj; // 删除 evaluate 对象
				lt.obj_ptr = nullptr; // 将 obj_ptr 设置为 nullptr
			}
		}
	}

	// 宏定义的接口实现，用于简化接口函数的定义
	LT_INTERFACE_IMPLEMENTATION(bool, false, runtime, login_account, (const ltobj& lt), ());

	LT_INTERFACE_IMPLEMENTATION(void, VOID_DEFAULT, runtime, logout_account, (const ltobj& lt), ());

	LT_INTERFACE_IMPLEMENTATION(bool, false, context, start_service, (const ltobj& lt), ());

	LT_INTERFACE_IMPLEMENTATION(bool, false, context, stop_service, (const ltobj& lt), ());

	LT_INTERFACE_IMPLEMENTATION(estid_t, INVALID_ESTID, context, place_order, (const ltobj& lt, offset_type offset, direction_type direction, const code_t& code, uint32_t count, double_t price, order_flag flag), (offset, direction, code, count, price, flag));
	
	LT_INTERFACE_IMPLEMENTATION(bool, false, context, cancel_order, (const ltobj& lt, estid_t estid), (estid));
	
	LT_INTERFACE_IMPLEMENTATION(const position_info&, default_position, context, get_position, (const ltobj& lt, const code_t& code), (code));
	
	LT_INTERFACE_IMPLEMENTATION(const order_info&, default_order, context, get_order, (const ltobj& lt, estid_t estid), (estid));

	LT_INTERFACE_IMPLEMENTATION(void, VOID_DEFAULT, context, subscribe, (const ltobj& lt, const std::set<code_t>& tick_data, tick_callback tick_cb), (tick_data, tick_cb));

	LT_INTERFACE_IMPLEMENTATION(void, VOID_DEFAULT, context, unsubscribe, (const ltobj& lt, const std::set<code_t>& tick_data), (tick_data));

	LT_INTERFACE_IMPLEMENTATION(daytm_t, 0, context, get_last_time, (const ltobj& lt), ());

	LT_INTERFACE_IMPLEMENTATION(void, VOID_DEFAULT, context, bind_realtime_event, (const ltobj& lt, const order_event& od_evt, cycle_callback init_cb, cycle_callback update_cb, cycle_callback destroy_cb), (od_evt, init_cb, update_cb, destroy_cb));

	LT_INTERFACE_IMPLEMENTATION(void, VOID_DEFAULT, evaluate, playback_history, (const ltobj& lt), ());

	LT_INTERFACE_IMPLEMENTATION(void, VOID_DEFAULT, evaluate, simulate_crossday, (const ltobj& lt, uint32_t trading_day), (trading_day));

	LT_INTERFACE_IMPLEMENTATION(daytm_t, 0, context, last_order_time, (const ltobj& lt), ());

	LT_INTERFACE_IMPLEMENTATION(const order_statistic&, default_statistic, context, get_order_statistic, (const ltobj& lt, const code_t& code), (code));

	LT_INTERFACE_IMPLEMENTATION(uint32_t, 0U, context, get_trading_day, (const ltobj& lt), ());
	
	LT_INTERFACE_IMPLEMENTATION(daytm_t, 0, context, get_close_time, (const ltobj& lt), ());

	LT_INTERFACE_IMPLEMENTATION(const char *, nullptr, context, get_include_config, (const ltobj& lt, const char* key), (key));

	LT_INTERFACE_IMPLEMENTATION(const tick_info&, default_tick, context, get_previous_tick, (const ltobj& lt, const code_t& code), (code));

	LT_INTERFACE_IMPLEMENTATION(const today_market_info&, default_today_market, context, get_today_market_info, (const ltobj& lt, const code_t& code), (code));
}
));